package cn.kgc.config;

import cn.kgc.utils.Constants;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * 配置类需要做的事情
 *
 * 1。制作队列
 * 2.制作交换机
 * 3.制作队列和交换机的绑定
 *
 * 附加： 1个死信交换机，死信队列，死信交换机和队列的绑定，正常的队列消息被超时或者被拒绝，进入死信中储存。
 *
 * Created by 北大课工场
 */
@Configuration
public class RabbitMQUtils {

    private Map<String, Object> args = new HashMap<>();

    @PostConstruct
    public void init(){
        // 设置该Queue的死信的信箱  死信交换器        deadLetterExchange
        args.put("x-dead-letter-exchange", Constants.DEAD_LETTER_EXCHANGE);
        // 设置死信routingKey                      消息的RoutingKey 路由 KEY  deadRoutingKey
        args.put("x-dead-letter-routing-key", Constants.DEAD_LETTER_ROUTINKEY);
    }

    //声明一个死信交换机  deadLetterExchange
    @Bean
    public TopicExchange deadLetterExchange() {
        return new TopicExchange(
                Constants.DEAD_LETTER_EXCHANGE,
                true,
                true);
    }

    //声明一个死信队列用来存放死信消息 dead.queue
    /**
     参数：String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments
     * 声明队列，如果Rabbit中没有此队列将自动创建
     * param1:队列名称
     * param2:是否持久化，重启启动Rabbitmq是否还存在这个队列
     * param3:是否独占连接，队列只允许在该连接中访问，如果connection连接关闭队列则自动删除,如果将此参数设置true可用于临时队列的创建
     * param4:队列不再使用时是否自动删除此队列
     * param5:参数，可以设置一个队列的扩展参数，比如：可设置存活时间
     */
    @Bean
    public Queue deadQueue() {
        return new Queue(Constants.DEAD_QUEUE,
                true,
                false,
                true,
                null);
    }

    // 将死信队列和死信的交换机绑定  BK: deadRoutingKey
    @Bean
    public Binding bindingDead() {
        return BindingBuilder.bind(deadQueue()).
                to(deadLetterExchange()).
                with(Constants.DEAD_LETTER_ROUTINKEY);  //BK --deadRoutingKey
    }


    //创建订单的队列 ，队列里面的信息，将来被消费者拒绝确认，不回到MQ队列那么就回到死信队列
    @Bean
    public Queue toCreateOrderQueue() {
        return new Queue(Constants.RabbitQueueName.TO_CREATE_ORDER, true, false, true, args);
    }

    //更新订单的队列
    @Bean
    public Queue toUpdateOrderQueue() {
        return new Queue(Constants.RabbitQueueName.TO_UPDATED_ORDER_QUEUE, true, false, true, args);
    }

    @Bean
    public Queue toUpdateGoodsQueue() {
        return new Queue(Constants.RabbitQueueName.TO_UPDATED_GOODS_QUQUE, true, false, true, args);
    }

    /**
     * 重置座位状态
     *
     * @return
     */
    @Bean
    public Queue toResetSeatQueue() {
//        args.put("x-dead-letter-exchange", Constants.DEAD_LETTER_EXCHANGE);
        // 设置死信routingKey
//        args.put("x-dead-letter-routing-key", Constants.DEAD_LETTER_ROUTINKEY);
        return new Queue(Constants.RabbitQueueName.TO_RESET_SEAT_QUQUE, true, false, true, args);
    }

    /**
     * 删除订单
     *
     * @return
     */
    @Bean
    public Queue toDelOrderQueue() {
        return new Queue(Constants.RabbitQueueName.TO_DEL_ORDER_QUQUE, true, false, true, args);
    }

    @Bean
    public Queue toUpdateOrderStateQueue(){
        return new Queue(Constants.RabbitQueueName.TO_UPDATE_ORDER_STATE, true, false, true, args);
    }




    /**
     * 重置联系人
     *
     * @return
     */
    @Bean
    public Queue toResetLinkUserQueue() {
        return new Queue(Constants.RabbitQueueName.TO_RESET_LINKUSER_QUQUE, true, false, true, args);
    }


    //TopicExchange
    @Bean
    TopicExchange topicExchange() {
        return new TopicExchange(
                Constants.RabbitQueueName.TOPIC_EXCHANGE,
                true,
                true);
    }


    @Bean
    public Binding bindingToCreateOrder() {
        return BindingBuilder.bind(toCreateOrderQueue()).to(topicExchange()).with("key.toCreateOrder");
    }

    @Bean
    public Binding bindingToUpdateOrder() {
        return BindingBuilder.bind(toUpdateOrderQueue()).to(topicExchange()).with("key.toUpdateOrder");
    }

    @Bean
    public Binding bindingToUpdateGoods() {
        return BindingBuilder.bind(toUpdateGoodsQueue()).to(topicExchange()).with("key.toUpdateGoods");
    }

    @Bean
    public Binding bindingToResetSeat() {
        return BindingBuilder.bind(toResetSeatQueue()).to(topicExchange()).with(Constants.RabbitQueueName.TO_RESET_SEAT_QUQUE);
    }

    @Bean
    public Binding bindingToDelOrder() {
        return BindingBuilder.bind(toDelOrderQueue()).to(topicExchange()).with(Constants.RabbitQueueName.TO_DEL_ORDER_QUQUE);
    }

    @Bean
    public Binding bindingToResetLinkUser() {
        return BindingBuilder.bind(toResetLinkUserQueue()).to(topicExchange()).with(Constants.RabbitQueueName.TO_RESET_LINKUSER_QUQUE);
    }

    @Bean
    public Binding bindingToUpdateOrderState() {
        return BindingBuilder.bind(toUpdateOrderStateQueue()).to(topicExchange()).with(Constants.RabbitQueueName.TO_UPDATE_ORDER_STATE);
    }

}
